<!-- components/Graph.vue -->
<template>
  <div ref="graphContainer" class="graph-container"></div>
</template>
  
  <script>
import G6 from "@antv/g6";
export default {
  name: "Graph",
  props: {
    nodes: {
      type: Array,
      required: true,
    },
    edges: {
      type: Array,
      required: true,
    },
  },
  watch: {
    nodes(newNodes) {
      // console.log("Nodes updated:", newNodes);
      this.updateGraph(newNodes, this.edges); // 数据变更时重新更新图表
    },
    edges(newEdges) {
      // console.log("Edges updated:", newEdges);
      this.updateGraph(this.nodes, newEdges);
    },
  },
  mounted() {
    this.$nextTick(() => {
      this.initGraph();
    });
  },
  methods: {
    // 更新数据
    updateGraph(nodes, edges) {
      // console.log("Updating graph with nodes and edges:", nodes, edges);
      if (this.graph) {
        // this.graph.destroy(); // 销毁当前图形
        // this.initGraph(); // 重新初始化图形

        // 去重后的节点和边
        const uniqueNodes = this.removeDuplicateNodes(nodes);
        const uniqueEdges = this.removeDuplicateEdges(edges);
        this.graph.changeData({ nodes: uniqueNodes, edges: uniqueEdges }); // 更新图形数据
        this.graph.render(); // 强制重新渲染
      }
    },
    initGraph() {
      const uniqueNodes = this.removeDuplicateNodes(this.nodes);
      const uniqueEdges = this.removeDuplicateEdges(this.edges);
      const data = {
        nodes: uniqueNodes,
        edges: uniqueEdges,
      };

      const graph = new G6.Graph({
        container: this.$refs.graphContainer, // 指定绘图容器
        width: this.$refs.graphContainer.offsetWidth, // 获取容器宽度
        height: this.$refs.graphContainer.offsetHeight, // 获取容器高度
        defaultNode: {
          // 节点类型
          type: "circle",
          size: [50], //节点大小
          color: "#5B8FF9", // 节点颜色
          style: {
            fill: "#9EC9FF", // 填充颜色
            lineWidth: 3, // 边框宽度
          },
          labelCfg: {
            style: {
              fill: "#ff0000", // 标签颜色
              fontSize: 20, // 标签字体大小
            },
          },
        },
        defaultEdge: {
          style: {
            stroke: "#e2e2e2", // 边的颜色
          },
        },
        modes: {
          default: ["drag-canvas", "zoom-canvas", "drag-node"], // 启用拖动画布、缩放画布和拖动节点
        },
      });

      graph.data(data);
      graph.render();
    },
    // 去重节点
    removeDuplicateNodes(nodes) {
      // 使用 Map 按 id 去重
      const nodeMap = new Map();
      nodes.forEach((node) => {
        if (!nodeMap.has(node.id)) {
          nodeMap.set(node.id, node);
        }
      });
      return Array.from(nodeMap.values()); // 转换回数组
    },

    // 去重边
    removeDuplicateEdges(edges) {
      const edgeSet = new Set();
      const uniqueEdges = [];

      edges.forEach((edge) => {
        const edgeKey = `${edge.source}-${edge.target}`; // 创建唯一标识符
        if (!edgeSet.has(edgeKey)) {
          edgeSet.add(edgeKey);
          uniqueEdges.push(edge); // 如果没见过这个边，则加入结果数组
        }
      });

      return uniqueEdges; // 返回去重后的边
    },
  },
  beforeDestroy() {
    if (this.graph) {
      this.graph.destroy(); // 清理图形实例
    }
  },
};
</script>
  
  <style scoped>
.graph-container {
  width: 100%;
  height: 100%; /* 可以根据需要调整 */
  background-color: #f0f2f5;
  border: 1px solid #ddd;
}
</style>
  